<template>
  <div class="swiper" @mouseenter="arrowEnter" @mouseleave="arrowLeave">
	<div class="top">
		<a href="#" class="pre" v-if="arrowShow" @click="pre" ref="pre" :style="{'left':dataPreDistance,'opacity':preShow}">
			<slot name="pre"><img src="../../assets/img/pre.svg" class="preImg"></slot>
		</a>
		
		<div class="wrap" ref="wrap" @mousedown="dragBegin" :style="{'width':wrapWidth,'height':wrapHeight}">
			<div class="content" ref="content" :style="{'margin-left':content_move,'transition':'all '+dataRelayTime/1000+'s'}">
				<slot name="content"></slot>
			</div>
		</div>
		
		<a href="#" class="next" v-if="arrowShow" @click="next" ref="next" :style="{'right':dataNextDistance,'opacity':nextShow}">
			<slot name="next"><img src="../../assets/img/next.svg" class="nextImg"></slot>
		</a>
	</div>
	<div class="bottom" v-if="pageShow" :style="{'margin-top':pageDistance,'height':bottomHeight}"  ref="bottom">
		<a class="pagerItem" href="" v-for="(v,i) in pageNum" @click="pageMove(i+1)" @mouseover="pagerCssChange(i)"
		@mouseout="callbackPagerCss">
			<slot name="page">
				<span class="circle"></span>
			</slot>
		</a>
	</div>
  </div>
</template>

<script>
	// 动画帧率不够可以试试这个库
	// import velocity from "velocity-animate";
  export default{
    name:'',
    data(){
      return {
				enter:false,
				activeIndex:0,
				beginPoint:0,
				overPoint:0,
				nowPage:1,
				pageNum:1,
				elementNum:0,
				elementWidth:0,
				elementHeight:0,
				wrapWidth:0,
				wrapHeight:0,
				contentHeight:0,
				contentWidth:0,
				contentMove:0,
				dragMove:0,
				backMove:0,
				arrowWidth:0,
				preShow:1,
				nextShow:1,
				dataRelayTime:this.relayTime,
				dataPreDistance:this.preDistance,
				dataNextDistance:this.nextDistance,
				bottomHeight:0,
				timer:null,
				isMove:false
      }
    },
	computed:{
		content_move(){
			return this.contentMove*-1+'px'
		}
	},
    methods:{
			addCss(dom,cssObj){
				for(let i in cssObj){
					dom.style[i]=cssObj[i]
				}
			},
			deleteCss(dom,cssObj){
				if(cssObj){
					for(let i in cssObj){
						dom.style[i]=''
					}
				}
				else dom.style={}
			},
			checkMove(){
				if(!this.isMove){
					this.isMove=true
					setTimeout(()=>{
						this.isMove=false
					},this.dataRelayTime)
					return true
				}
				return false
			},
			// 上一页
      pre(){
				let e=window.event
				e.preventDefault()
				if(this.checkMove()){
					if(this.nowPage<=1){
						if(!this.loop)
							return
						else this.loopPre()
					}
					else this.pageMove(--this.nowPage)
				}
				
			},
			// 下一页
			next(){
				let e=window.event
				e.preventDefault()
				if(this.checkMove()){
					if(this.nowPage>=this.pageNum){
						if(!this.loop)
							return
						else this.loopNext()
					}
					else this.pageMove(++this.nowPage)
				}
			},
			// 翻页
			pageMove(i){
				 let e=window.event,prePage=this.nowPage,time=0
				 if(e)
					e.preventDefault()
				 this.nowPage=i
				 this.dataRelayTime=this.relayTime
				 if(this.isChangePage)
					this.contentMove=this.elementWidth*this.showNum*this.nowPage
				 else this.contentMove=this.elementWidth*(this.nowPage-1+this.showNum)
				 this.activeIndex=i-1
				 if(this.is3d){
					 if(i-prePage>1){
						 for(let j=0;j<i-prePage;j++){
							 setTimeout(()=>{
								 this.dataRelayTime=this.relayTime/(i-prePage)
								 this.change3dCss(this.showNum+prePage+j+1)
							 },time*0.6)
							 time+=this.relayTime/(i-prePage)
						 }
					 }
					 else if(i-prePage<-1){
						 for(let j=0;j>i-prePage;j--){
							 setTimeout(()=>{
								 this.dataRelayTime=this.relayTime/Math.abs(i-prePage)
								 this.change3dCss(this.showNum+prePage+j-1)
								 console.log(i-prePage);
							 },time*0.6)
							 time+=this.relayTime/Math.abs(i-prePage)
						 }
					 }
					 else
						this.change3dCss(this.showNum+this.nowPage)
				 }
				 this.pagerCssChange(i-1)
			},
			// 循环模式下，最后一页的特殊处理
			loopNext(){
				this.dataRelayTime=this.relayTime
				if(this.isChangePage)
					this.contentMove=this.elementWidth*this.showNum*(this.pageNum+1)
				else this.contentMove+=this.elementWidth
				if(this.is3d){
					this.change3dCss(this.showNum+this.pageNum+1)
					setTimeout(()=>{
						this.dataRelayTime=0
						this.change3dCss(this.showNum+1)
					},this.dataRelayTime)
				}
					
				setTimeout(()=>{
					this.dataRelayTime=0
					this.contentMove=this.elementWidth*this.showNum
					this.nowPage=1
				},this.dataRelayTime)
				this.pagerCssChange(0)
			},
			loopPre(){
				this.dataRelayTime=this.relayTime
				if(this.isChangePage)
					this.contentMove=0
				else this.contentMove-=this.elementWidth
				if(this.is3d){
					this.change3dCss(this.showNum)
					setTimeout(()=>{
						this.dataRelayTime=0
						this.change3dCss(this.showNum+this.pageNum)
					},this.dataRelayTime)
				}
					
				setTimeout(()=>{
					this.dataRelayTime=0
					if(this.isChangePage)
						this.contentMove=this.elementWidth*this.showNum*this.pageNum
					else this.contentMove=this.elementWidth*(this.pageNum-1+this.showNum)
					this.nowPage=this.pageNum
				},this.dataRelayTime)
				this.pagerCssChange(this.pageNum-1)
			},
			change3dCss(activePage){
				let active3dCss={
					transform: "scale(2,1.5)",
					"transform-origin":"center,center",
					transition:"all "+this.dataRelayTime/1000+"s",
					opacity:1,
					"z-index":5,
					...this.active3dCss
				}
				for(let i of this.$refs.content.children){
					this.deleteCss(i,active3dCss)
				}
				let temp=1,css={
					transform: "scale(1.5,1)",
					transition:"all "+this.dataRelayTime/1000+"s",
				}
				this.addCss(this.$refs.content.children[activePage],{
					...active3dCss
				})
				for(let i=Math.ceil(this.showNum/2)*(-1);i<=Math.ceil(this.showNum/2);i++){
					if(!i)
						continue
					if(temp%2){
						css["transform-origin"]="right"
					}else{
						css["transform-origin"]="left"
					}
					if(activePage+i<this.$refs.content.children.length&&activePage+i>-1){
						this.addCss(this.$refs.content.children[activePage+i],css)
					}
					temp++
				}
				// console.log(activePage,this.$refs.content.children[activePage]);
			},
			pagerCssChange(i){
				if(this.pageShow){
					this.addCss(this.$refs.bottom.children[i].children[0],this.activePageCss)
					for(let j=0;j<this.$refs.bottom.children.length;j++){
						if(j!=i){
							this.deleteCss(this.$refs.bottom.children[j].children[0])
						}
					}
				}
			},
			callbackPagerCss(){
				this.pagerCssChange(this.activeIndex)
			},
			// 切换页面的箭头出现
			arrowSkipIn(){
				this.dataPreDistance=parseFloat(this.dataPreDistance)+this.arrowWidth+'px'
				this.dataNextDistance=parseFloat(this.dataNextDistance)+this.arrowWidth+'px'
				this.preShow=1
				this.nextShow=1
			},
			// 切换页面的箭头消失
			arrowSkipOut(){
				this.dataPreDistance=parseFloat(this.dataPreDistance)-this.arrowWidth+'px'
				this.dataNextDistance=parseFloat(this.dataNextDistance)-this.arrowWidth+'px'
				this.preShow=0
				this.nextShow=0
			},
			// 鼠标悬停时停止自动播放
			arrowEnter(){
				clearInterval(this.timer)
				if(this.arrowMode=='skip'&&this.enter==false){
					this.arrowSkipIn()
					this.enter=true
				}
			},
			// 鼠标离开时恢复自动播放
			arrowLeave(){
				this.autoRelay()
				if(this.arrowMode=='skip'&&this.enter==true){
					this.arrowSkipOut()
					this.enter=false
				}
			},
			// 如果无法使用上(下)一页的箭头，箭头会变成半透明
			checkArrow(){
				if(this.nowPage<=1&&!this.loop){
						this.addCss(this.$refs.pre,this.deactiveArrowCss)
				}
				else {
					this.deleteCss(this.$refs.pre,this.deactiveArrowCss)
				}
				if(this.nowPage>=this.pageNum&&!this.loop){
						this.addCss(this.$refs.next,this.deactiveArrowCss)
				}
				else {
					this.deleteCss(this.$refs.next,this.deactiveArrowCss)
				}
			},
			// 鼠标移出时产生透明度渐变
			arrowSkip(){
				if(this.enter)
					this.checkArrow()
				else this.preShow=this.nextShow=0
			},
			checkArrowSkip(){
				if(this.arrowMode=='skip'){
					this.arrowSkip()
				}
				else this.checkArrow()
			},
			initInterval(){
				for(let i of this.$refs.content.children){
					let css=getComputedStyle(this.$refs.content.children[0].children[0]||this.$refs.content.children[0],null)
					if(css.marginLeft!='0px'){
						i.style.marginRight=css.marginLeft
					}
					if(css.marginRight!='0px'){
						i.style.marginRight=css.marginRight
					}
					if(this.interval!='0px'){
						i.style.marginRight=this.interval
					}
				}
			},
			// 取元素尺度
			getScale(){
				this.getWidth()
				this.getHeight()
			},
			getWidth(){
				this.arrowWidth=this.$refs?.next?.clientWidth
				// 取第零个成员宽度。。。
				let width=this.$refs.content.children[0].clientWidth
				if(width<1){
					this.$refs.content.style.display='flex'
					width=this.$refs.content.children[0].clientWidth
				}
				else{
					for(let i of this.$refs.content.children){
						i.style.float='left'
					}
				}
				let marginLeft=parseFloat(getComputedStyle(this.$refs.content.children[0],null).marginLeft)
				let marginRight=parseFloat(getComputedStyle(this.$refs.content.children[0],null).marginRight)
				let margin=parseFloat(getComputedStyle(this.$refs.content.children[0],null).margin)
				this.elementWidth=width
				// 取边距+宽度
				if(margin){
					this.elementWidth+=margin
				}
				if(marginRight){
					this.elementWidth+=marginRight
				}
				if(marginLeft){
					this.elementWidth+=marginLeft
				}
				this.wrapWidth=this.elementWidth*(this.showNum-1)+width+'px'
				this.$refs.content.style.width=this.elementWidth*(this.pageNum+2)*this.showNum+'px'
			},
			getHeight(){
				let height=this.$refs.content.children[0].clientHeight
				let margin=parseFloat(getComputedStyle(this.$refs.content.children[0],null).margin)
				let marginTop=parseFloat(getComputedStyle(this.$refs.content.children[0],null).marginTop)
				let marginBottom=parseFloat(getComputedStyle(this.$refs.content.children[0],null).marginBottom)
				this.elementHeight=height
				if(margin){
					this.elementHeight+=margin
				}
				if(marginTop)
					this.elementHeight+=marginTop
				if(marginBottom)
					this.elementHeight+=marginBottom
				if(this.is3d)
					this.wrapHeight=this.elementHeight*1.5+'px'
				else this.wrapHeight=this.elementHeight+'px'
				this.$refs.content.style.height=this.$refs.wrap.style.height=this.elementHeight+'px'
			},
			// 定义箭头与界面边缘的距离
			initArrowDis(){
				this.dataPreDistance=this.arrowWidth*(-1)*2
				this.dataNextDistance=this.arrowWidth*(-1)*2
				if(parseInt(this.arrowDistance)!=0){
				  this.dataPreDistance+=parseInt(this.arrowDistance)*(-1)
					this.dataNextDistance+=parseInt(this.arrowDistance)*(-1)
				}
				this.dataPreDistance+='px'
				this.dataNextDistance+='px'
			},
			dragBegin(e){
				if(!this.isDrag){
					return
				}
				this.beginPoint=event.clientX
				this.backMove=this.dragMove=this.contentMove
				document.addEventListener('mousemove',this.draging,false)
				document.addEventListener('mouseup',this.dragOver,false)
			},
			draging(e){
				let point=event.clientX,temp=this.beginPoint-point
				this.dataRelayTime=0
				this.contentMove=this.beginPoint-point+this.dragMove
			},
			dragOver(e){
				this.dataRelayTime=this.relayTime/2
				this.overPoint=event.clientX
				let move=this.beginPoint-this.overPoint
				if(move>200){
					this.next()
				}
				else if(move<-200){
					this.pre()
				}
				else this.contentMove=this.backMove
				// this.dragMove=this.contentMove
				document.removeEventListener('mousemove',this.draging)
				document.removeEventListener('mouseup',this.dragOver)
			},
			// 禁止拖动图片元素
			banImgDrag(){
				for(let i of this.$refs.content.children){
					for(let j of i.getElementsByTagName('img')){
						j.onmousedown=()=>event.preventDefault();
					}
				}
			},
			autoRelay(){
				if(this.auto){
					clearInterval(this.timer)
					this.timer=setInterval(()=>{
						this.next()
					},this.autoSpeed)
				}
			},
			createBlank(){
				let div=document.createElement('div')
				div.style.width=this.elementWidth+'px'
				div.style.height=this.elementHeight+'px'
				div.style.float='left'
				return div
			},
			initElementNum(){
				this.elementNum=this.$refs.content.children.length
			},
			initpageNum(){
				this.initElementNum()
				if(this.isChangePage)
					this.pageNum=Math.ceil(this.elementNum/this.showNum)
				else this.pageNum=this.elementNum
			},
			initDisplay(){
				if(this.is3d){
					this.$refs.wrap.style.display='flex'
					this.$refs.wrap.style['align-items']='center'
					this.$refs.content.style.display='flex'
				}
				else this.$refs.content.style.display='block'
			},
			initPager(){
				if(this.pageShow){
					this.bottomHeight=this.$refs.bottom.children[0].clientHeight*2+'px'
					this.initPagerNum()
				}
			},
			// 初始化分页器的数字
			initPagerNum(){
				// 我也不知道为什么要定时器
				setTimeout(()=>{
					if(this.pageNumShow){
						for(let i=0;i<this.$refs.bottom.children.length;i++){
							this.$refs.bottom.children[i].children[0].innerText=i+1
						}
					}
				},0)
			},
			// 初始化循环，似乎无法直接控制传入的div
			initPageCirculate(){
				let firsts=[]
				let lasts=[]
				for(let i=0;i<this.showNum;i++){
					let first=this.$refs.content.children[i].cloneNode(true)
					firsts.push(first)
				}
				let lastLength=this.elementNum%this.showNum==0?this.showNum:this.elementNum%this.showNum
				for(let i=lastLength;i>0;i--){
					let last=this.$refs.content.children[this.elementNum-i].cloneNode(true)
					lasts.push(last)
				}
				let lastBlankLength=this.showNum-lastLength
				for(let i=0;i<lastBlankLength;i++){
					this.$refs.content.appendChild(this.createBlank())
					lasts.unshift(this.createBlank())
				}
				for(let i of firsts){
					this.$refs.content.appendChild(i)
				}
				for(let i of lasts){
					this.$refs.content.insertBefore(i,this.$refs.content.children[0])
				}
				this.dataRelayTime=0
				this.contentMove=this.showNum*this.elementWidth
			},
			initOneCirculate(){
				let firsts=[]
				let lasts=[]
				for(let i=0;i<this.showNum;i++){
					let first=this.$refs.content.children[i].cloneNode(true)
					let last=this.$refs.content.children[this.elementNum-this.showNum+i].cloneNode(true)
					firsts.push(first)
					lasts.unshift(last)
				}
				for(let i of firsts){
					this.$refs.content.appendChild(i)
				}
				for(let i of lasts){
					this.$refs.content.insertBefore(i,this.$refs.content.children[0])
				}
				this.dataRelayTime=0
				this.contentMove=this.showNum*this.elementWidth
			},
			initCirculate(){
				if(this.isChangePage)
					this.initPageCirculate()
				else {
					this.initOneCirculate()
				}
				if(this.is3d){
					this.dataRelayTime=0
					this.change3dCss(this.showNum+this.nowPage)
				}
					
			}
    },
	props:{
	  showNum:{
		  type:Number,
		  default(){
				return 1
		  }
	  },
		isChangePage:{
		  type:Boolean,
		  default(){
				return true
		  }
		},
		is3d:{
		  type:Boolean,
		  default(){
				return false
		  }
		},
		relayTime:{
		  type:Number,
		  default(){
				return 2000
		  }
	  },
	  arrowDistance:{
		  type:String,
		  default(){
				return "0px"
		  }
	  },
	  arrowMode:{
		  type:String,
		  default(){
				return ""
		  }
	  },
	  preDistance:{
		  type:String,
		  default(){
				return null
		  }
	  },
	  nextDistance:{
		  type:String,
		  default(){
				return null
		  }
	  },
		pageDistance:{
			type:String,
			default(){
				return "0px"
			}
		},
	  interval:{
		  type:String,
		  default(){
				return "0px"
		  }
	  },
		isDrag:{
			type:Boolean,
			default(){
				return false
			}
		},
		arrowShow:{
			type:Boolean,
			default(){
				return false
			}
		},
		pageShow:{
			type:Boolean,
			default(){
				return false
			}
		},
		pageNumShow:{
			type:Boolean,
			default(){
				return false
			}
		},
		auto:{
			type:Boolean,
			default(){
				return false
			}
		},
		autoSpeed:{
			type:Number,
			default(){
				return 3000
			}
		},
		loop:{
			type:Boolean,
			default(){
				return false
			}
		},
		activePageCss:{
			type:Object,
			default(){
				return {
					"transform-origin":"center center",
					transition:"all 0.5s",
					"background-color":"#626262",
					"line-height":"20px"
				}
			}
		},
		deactiveArrowCss:{
			type:Object,
			default(){
				return {
					background:"yellow",
					opacity:0.3
				}
			}
		},
		active3dCss:{
			type:Object,
			default(){
				return {
					
				}
			}
		}
	},
	created() {
		
	},
	mounted() {
		this.initpageNum()
		this.initPager()
		this.initInterval()
		this.getScale()
		this.initDisplay()
	  this.banImgDrag()
	  this.initArrowDis()
		this.autoRelay()
		this.initCirculate()
		this.pagerCssChange(0)
	}
  }
</script>

<style scoped>
	.top{
		display: flex;
		align-items: center;
		justify-content: center;
		position: relative;
	}
	.pre,.next{
		position: absolute;
		transition: all 1s;
	}
	.preImg,.nextImg{
		background-color: var(--bcc-grey);
		height: 80px;
		width: 40px;
	}
	.wrap{
		overflow: hidden;
	}
	.circle{
		display: inline-block;
		width: 15px;
		height: 15px;
		background-color: #cbcbcb;
		border-radius: 50%;
		transition: all 0.2s;
		color: #ffffff;
		text-align: center;
		font-size: 8px;
		line-height: 15px;
	}
	.circle:nth-of-type(n+1){
		margin-left: 10px;
	}
	.bottom{
		margin: 0 auto;
		display: flex;
		align-items: center;
		justify-content: center;
	}
	.pagerItem{
		display: inline-block;
	}
</style>
